package com.app.coderead;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Enumeration;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.*;

/**
 * 
 * @author Flyman
 * 
 */
@SuppressWarnings("serial")
public class CodereadServlet extends HttpServlet {
    // private static final String CODE_READ_URL = "http://localhost:8888/uploadcode";
    private static final String CODE_READ_URL = "http://readtoshow.appspot.com/uploadcode";
    private static final String CHARSET = "UTF-8";
    private static final String CRLF = "\r\n";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
            IOException {
        processRequest(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        processRequest(req, resp);
    }

    @SuppressWarnings("unchecked")
    public void processRequest(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String TAG = this.getClass().getName();
        Logger log = Logger.getLogger(TAG);

        URL url = new URL(CODE_READ_URL);
        String boundary = Long.toHexString(System.currentTimeMillis());

        URLConnection connection = url.openConnection();
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(10000);
        connection.setDoOutput(true);
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

        OutputStream connectOut = null;
        PrintWriter connectOutWrite = null;

        String docName = req.getParameter("doc");

        File file = new File("WEB-INF/doc/" + docName + ".java");
        // 將檔案存為串流
        InputStream in = new FileInputStream(file);

        connectOut = connection.getOutputStream();
        // true = autoFlush
        connectOutWrite = new PrintWriter(new OutputStreamWriter(connectOut, CHARSET), true);

        // 取出 form field value 並組為connectOut內容
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String nextElement = parameterNames.nextElement();
            String parameter = req.getParameter(nextElement);
            log.info("parameter value : " + parameter);
            connectOutWrite.append("--" + boundary).append(CRLF);
            connectOutWrite.append("Content-Disposition: form-data; name=\"" + nextElement + "\"")
                    .append(CRLF);
            connectOutWrite.append("Content-Type: text/plain; charset=" + CHARSET).append(CRLF);
            connectOutWrite.append(CRLF);
            connectOutWrite.append(parameter).append(CRLF).flush();

        }

        String fileName = "doc";
        String fieldName = file.getName();
        connectOutWrite.append("--" + boundary).append(CRLF);
        connectOutWrite.append(
                "Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\""
                        + fileName + "\"").append(CRLF);
        connectOutWrite.append("Content-Type: " + URLConnection.guessContentTypeFromName(fileName))
                .append(CRLF);
        connectOutWrite.append("Content-Transfer-Encoding: binary").append(CRLF);
        connectOutWrite.append(CRLF).flush();
        // ------------------------------------------------------
        try {
            byte[] buffer = new byte[1024];
            for (int length = 0; (length = in.read(buffer)) > 0;) {
                connectOut.write(buffer, 0, length);
            }

            // Important! Output cannot be closed. Close of writer
            // will close output as well.
            connectOut.flush();

        } finally {
            if (in != null) {
                try {
                    // close the stream from user upload file
                    in.close();
                } catch (IOException e) {
                    log.info("fail to close the stream from user upload file");
                }
            }
        }
        // CRLF is important! It indicates end of binary boundary.
        connectOutWrite.append(CRLF).flush();
        // End of multipart/form-data.
        connectOutWrite.append("--" + boundary + "--").append(CRLF).flush();

        // to browser
        resp.setCharacterEncoding(CHARSET);
        PrintWriter writer = resp.getWriter();

        BufferedReader connectIn = null;

        int status = ((HttpURLConnection) connection).getResponseCode();
        switch (status) {
        case java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT:// 504
            log.info("連線網址逾時!");
            break;
        case java.net.HttpURLConnection.HTTP_FORBIDDEN:// 403
            log.info("連線網址禁止!");
            break;
        case java.net.HttpURLConnection.HTTP_INTERNAL_ERROR:// 500
            log.info("連線網址錯誤或不存在!");
            break;
        case java.net.HttpURLConnection.HTTP_NOT_FOUND:// 404
            log.info("連線網址不存在!");
            break;
        case java.net.HttpURLConnection.HTTP_OK:
            // reads the response of connection and output it inside the servlet
            // content
            try {
                connectIn = new BufferedReader(new InputStreamReader(connection.getInputStream(),
                        CHARSET));
                String line = null;
                while (null != (line = connectIn.readLine())) {
                    writer.append(line).append(CRLF);
                }

            } finally {
                if (connectIn != null) {
                    connectIn.close();
                }
            }
            break;

        }
    }
}
